home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / grafica / pvrgjpeg / codec.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  15KB  |  688 lines

  1. /*************************************************************
  2. Copyright (C) 1990, 1991, 1993 Andy C. Hung, all rights reserved.
  3. PUBLIC DOMAIN LICENSE: Stanford University Portable Video Research
  4. Group. If you use this software, you agree to the following: This
  5. program package is purely experimental, and is licensed "as is".
  6. Permission is granted to use, modify, and distribute this program
  7. without charge for any purpose, provided this license/ disclaimer
  8. notice appears in the copies.  No warranty or maintenance is given,
  9. either expressed or implied.  In no event shall the author(s) be
  10. liable to you or a third party for any special, incidental,
  11. consequential, or other damages, arising out of the use or inability
  12. to use the program for any purpose (or the loss of data), even if we
  13. have been advised of such possibilities.  Any public reference or
  14. advertisement of this source code should refer to it as the Portable
  15. Video Research Group (PVRG) code, and not by any author(s) (or
  16. Stanford University) name.
  17. *************************************************************/
  18. /*
  19. ************************************************************
  20. codec.c
  21.  
  22. This file contains much of the transform coding routines to manipulate
  23. the Huffman stream.
  24.  
  25. ************************************************************
  26. */
  27.  
  28. /*LABEL codec.c */
  29.  
  30. /* Include files. */
  31. #include "globals.h"
  32. #include "csize.h"
  33.  
  34. /* Definitions for renaming functions. */
  35.  
  36. #define fputv meputv
  37. #define fgetv megetv
  38.  
  39. /* Exportable functions. */
  40.  
  41. /*PUBLIC*/
  42.  
  43. extern void FrequencyAC();
  44. extern void EncodeAC();
  45. extern void DecodeAC();
  46. extern int DecodeDC();
  47. extern void FrequencyDC();
  48. extern void EncodeDC();
  49. extern void ResetCodec();
  50. extern void ClearFrameFrequency();
  51. extern void AddFrequency();
  52. extern void InstallFrequency();
  53. extern void InstallPrediction();
  54. extern void PrintACEhuff();
  55. extern void PrintDCEhuff();
  56. extern int SizeACEhuff();
  57. extern int SizeDCEhuff();
  58.  
  59. extern int LosslessDecodeDC();
  60. extern void LosslessFrequencyDC();
  61. extern void LosslessEncodeDC();
  62.  
  63. /*PRIVATE*/
  64.  
  65. /* Imported Variables. */
  66.  
  67. extern int bit_set_mask[]; /* Used for testing sign extension. */
  68. extern int Loud;           /* General debug level. */
  69. extern FRAME *CFrame;      /* Frame parameter. */
  70. extern IMAGE *CImage;      /* Image parameter. */
  71. extern SCAN *CScan;        /* Scan parameter. */
  72.  
  73. /* Local Variables */
  74.  
  75. static int *LastDC=NULL;         /* Last DC value for DPCM. */
  76. static int *ACFrequency=NULL;    /* AC Frequency table to accum. statistics.*/
  77. static int *DCFrequency=NULL;    /* DC Frequency table to accum. statistics.*/
  78. static int extend_mask[]={       /* Used for sign extensions. */
  79. 0xFFFFFFFE,
  80. 0xFFFFFFFC,
  81. 0xFFFFFFF8,
  82. 0xFFFFFFF0,
  83. 0xFFFFFFE0,
  84. 0xFFFFFFC0,
  85. 0xFFFFFF80,
  86. 0xFFFFFF00,
  87. 0xFFFFFE00,
  88. 0xFFFFFC00,
  89. 0xFFFFF800,
  90. 0xFFFFF000,
  91. 0xFFFFE000,
  92. 0xFFFFC000,
  93. 0xFFFF8000,
  94. 0xFFFF0000,
  95. 0xFFFE0000,
  96. 0xFFFC0000,
  97. 0xFFF80000,
  98. 0xFFF00000
  99. };
  100.  
  101. /*START*/
  102.  
  103. /*BFUNC
  104.  
  105. FrequencyAC() is used to accumulate the Huffman codes for the input
  106. matrix. The Huffman codes are not actually stored but rather the count
  107. of each code is stored so that construction of a Custom Table is
  108. possible.
  109.  
  110. EFUNC*/
  111.  
  112. void FrequencyAC(matrix)
  113.      int *matrix;
  114. {
  115.   BEGIN("FrequencyAC");
  116.   int i,k,r,ssss,cofac;
  117.  
  118.   for(k=r=0;++k < BLOCKSIZE;)  /* Like EncodeAC below except don't write out */
  119.     {
  120.       cofac = abs(matrix[k]);           /* Find absolute size */
  121.       if (cofac < 256)
  122.     {
  123.       ssss = csize[cofac];
  124.     }
  125.       else
  126.     {
  127.       cofac = cofac >> 8;
  128.       ssss = csize[cofac] + 8;
  129.     }
  130.       if (matrix[k] == 0)               /* Check for zeroes */
  131.     {
  132.       if (k == BLOCKSIZE-1)         /* If end of block, then process */
  133.         {
  134. #ifdef CODEC_DEBUG
  135.           printf("AC FEncoding EOB %d\n",0);
  136. #endif
  137.           ACFrequency[0]++;         /* Increment EOB frequency */
  138.           break;
  139.         }
  140.       r++;
  141.     }
  142.       else
  143.     {
  144.       while(r > 15)                 /* Convert, r, ssss, into RLE */
  145.         {
  146. #ifdef CODEC_DEBUG
  147.           printf("AC FEncoding OVFL %d\n",240);
  148. #endif
  149.           ACFrequency[240]++;       /* Increment ZRL extender freq */
  150.           r -= 16;
  151.         }
  152.       i = 16*r + ssss;              /* Make code */
  153.       r = 0;
  154. #ifdef CODEC_DEBUG
  155.       printf("AC FEncoding nnnnssss %d\n",i);
  156. #endif
  157.       ACFrequency[i]++;             /* Increment frequency of such code. */
  158.     }
  159.     }
  160. }
  161.  
  162. /*BFUNC
  163.  
  164. EncodeAC() takes the matrix and encodes it by passing the values
  165. of the codes found to the Huffman package.
  166.  
  167. EFUNC*/
  168.  
  169. void EncodeAC(matrix)
  170.      int *matrix;
  171. {
  172.   BEGIN("EncodeAC");
  173.   int i,k,r,ssss,cofac;
  174.  
  175.   for(k=r=0;++k<BLOCKSIZE;)
  176.     {
  177.       cofac = abs(matrix[k]);             /* Find absolute size */
  178.       if (cofac < 256)
  179.     {
  180.       ssss = csize[cofac];
  181.     }
  182.       else
  183.     {
  184.       cofac = cofac >> 8;
  185.       ssss = csize[cofac] + 8;
  186.     }
  187.       if (matrix[k] == 0)                /* Check for zeroes */
  188.     {
  189.       if (k == BLOCKSIZE-1)
  190.         {
  191. #ifdef CODEC_DEBUG
  192.           printf("AC Encoding EOB %d\n",0);
  193. #endif
  194.           EncodeHuffman(0);
  195.           break;
  196.         }
  197.       r++;                           /* Increment run-length of zeroes */
  198.     }
  199.       else
  200.     {
  201.       while(r > 15)                 /* If run-length > 15, time for  */
  202.         {                           /* Run-length extension */
  203. #ifdef CODEC_DEBUG
  204.           printf("AC Encoding OVFL %d\n",240);
  205. #endif
  206.           EncodeHuffman(240);
  207.           r -= 16;
  208.         }
  209.       i = 16*r + ssss;              /* Now we can find code byte */
  210. #ifdef CODEC_DEBUG
  211.       printf("AC Encoding nnnnssss %d\n",i);
  212. #endif
  213.       r = 0;
  214.       EncodeHuffman(i);             /* Encode RLE code */
  215.       if (matrix[k]< 0)             /* Follow by significant bits */
  216.         {
  217.           fputv(ssss,matrix[k]-1);
  218.         }
  219.       else
  220.         {
  221.           fputv(ssss,matrix[k]);
  222.         }
  223.  
  224.     }
  225.     }
  226. }
  227.  
  228. /*BFUNC
  229.  
  230. DecodeAC() is used to decode the AC coefficients from the stream in
  231. the stream package. The information generated is stored in the matrix
  232. passed to it.
  233.  
  234. EFUNC*/
  235.  
  236. void DecodeAC(matrix)
  237.      int *matrix;
  238. {
  239.   BEGIN("DecodeAC");
  240.   int k,r,s,n;
  241.   register int *mptr;
  242.  
  243.   for(mptr=matrix+1;mptr<matrix+BLOCKSIZE;mptr++)  /* Set all values to zero */
  244.     {
  245.       *mptr=0;
  246.     }
  247.  
  248.   for(k=1;k<BLOCKSIZE;)  /* JPEG Mistake */
  249.     {
  250.       r = DecodeHuffman();                         /* Decode Huffman */
  251. #ifdef CODEC_DEBUG
  252.       printf("Raw AC Input: %d\n",r);
  253. #endif
  254.       s = r & 0xf;                                 /* Find significant bits */
  255.       n = (r >> 4) & 0xf;                          /* n = run-length */
  256.       if (s)
  257.     {
  258.       if ((k += n)>=BLOCKSIZE) break;          /* JPEG Mistake */
  259.       matrix[k] = fgetv(s);                    /* Get s bits */
  260.  
  261.       s--; /* Align s */
  262.       if ((matrix[k] & bit_set_mask[s]) == 0)  /* Also (1 << s) */
  263.         {
  264.           matrix[k] |= extend_mask[s];         /* Also  (-1 << s) + 1 */
  265.           matrix[k]++;                         /* Increment 2's c */
  266.         }
  267.       k++;                                     /* Goto next element */
  268.     }
  269.       else if (n == 15)                      /* Zero run length code extnd */
  270.     k += 16;
  271.       else
  272.     {
  273.       break;
  274.     }
  275.     }
  276. }
  277.  
  278. /*BFUNC
  279.  
  280. DecodeDC() is used to decode a DC value from the input stream.
  281. It returns the actual number found.
  282.  
  283. EFUNC*/
  284.  
  285. int DecodeDC()
  286. {
  287.   BEGIN("DecodeDC");
  288.   int s,diff;
  289.  
  290.   s = DecodeHuffman();
  291. #ifdef CODEC_DEBUG
  292.   printf("DC Decode sig. %d\n",s);
  293. #endif
  294.  
  295.   if (s)
  296.     {
  297.       diff = fgetv(s);
  298.       s--;                                  /* 2's Bit Align */
  299. #ifdef CODEC_DEBUG
  300.       printf("Raw DC Decode %d\n",diff);
  301. #endif
  302.       if ((diff & bit_set_mask[s]) == 0)
  303.     {
  304.       diff |= extend_mask[s];
  305.       diff++;
  306.     }
  307.       diff += *LastDC;                      /* Change the last DC */
  308.       *LastDC = diff;
  309.     }
  310.   return(*LastDC);
  311. }
  312.  
  313. /*BFUNC
  314.  
  315. FrequencyDC() is used to accumulate statistics on what DC codes occur
  316. most frequently.
  317.  
  318. EFUNC*/
  319.  
  320. void FrequencyDC(coef)
  321.      int coef;
  322. {
  323.   BEGIN("FrequencyDC");
  324.   int s,diff,cofac;
  325.  
  326.   diff = coef - *LastDC;         /* Do DPCM */
  327.   *LastDC = coef;
  328.   cofac = abs(diff);
  329.   if (cofac < 256)               /* Find "code" */
  330.     {
  331.       s = csize[cofac];
  332.     }
  333.   else
  334.     {
  335.       cofac = cofac >> 8; 
  336.       s = csize[cofac] + 8;
  337.     }
  338. #ifdef CODEC_DEBUG
  339.   printf("DC FEncoding Difference %d Size %d\n",diff,s);
  340. #endif
  341.   DCFrequency[s]++;              /* Increment frequency of such code */
  342. }
  343.  
  344. /*BFUNC
  345.  
  346. EncodeDC() encodes the input coefficient to the stream using the
  347. currently installed DC Huffman table.
  348.  
  349. EFUNC*/
  350.  
  351. void EncodeDC(coef)
  352.      int coef;
  353. {
  354.   BEGIN("EncodeDC");
  355.   int s,diff,cofac;
  356.  
  357.   diff = coef - *LastDC;
  358.   *LastDC = coef;                /* Do DPCM */
  359.   cofac = abs(diff);
  360.   if (cofac < 256)
  361.     {
  362.       s = csize[cofac];          /* Find true size */
  363.     }
  364.   else
  365.     {
  366.       cofac = cofac >> 8;
  367.       s = csize[cofac] + 8;
  368.     }
  369. #ifdef CODEC_DEBUG
  370.   printf("DC Encoding Difference %d Size %d\n",diff,s);
  371. #endif
  372.   EncodeHuffman(s);              /* Encode size */
  373.   if (diff < 0)                  /* Encode difference */
  374.     {
  375.       diff--;
  376.     }
  377.   fputv(s,diff);
  378. }
  379.  
  380. /*BFUNC
  381.  
  382. ResetCodec() is used to reset all the DC prediction values. This
  383. function is primarily used for initialization and resynchronization.
  384.  
  385. EFUNC*/
  386.  
  387. void ResetCodec()
  388. {
  389.   BEGIN("ResetCodec");
  390.   int i;
  391.   
  392.   for(i=0;i<CScan->NumberComponents;i++)
  393.     {
  394.       *CScan->LastDC[i] = 0;                /* Sets all DC predictions to 0 */
  395.     }
  396. }
  397.  
  398. /*BFUNC
  399.  
  400. ClearFrameFrequency() clears all current statistics.
  401.  
  402. EFUNC*/
  403.  
  404. void ClearFrameFrequency()
  405. {
  406.   int i;
  407.   int *iptr;
  408.   
  409.   for(i=0;i<CScan->NumberComponents;i++)
  410.     {
  411.       *CScan->LastDC[i] = 0;
  412.       for(iptr=CScan->ACFrequency[i];
  413.       iptr<CScan->ACFrequency[i]+257;iptr++)
  414.     {
  415.       *iptr = 0;
  416.     }
  417.       for(iptr=CScan->DCFrequency[i];
  418.       iptr<CScan->DCFrequency[i]+257;iptr++)
  419.     {
  420.       *iptr = 0;
  421.     }
  422.     }
  423. }
  424.  
  425. /*BFUNC
  426.  
  427. AddFrequency() is used to combine the first set of frequencies denoted
  428. by the first pointer to the second set of frequencies denoted by the
  429. second pointer.
  430.  
  431. EFUNC*/
  432.  
  433. void AddFrequency(ptr1,ptr2)
  434.      int *ptr1;
  435.      int *ptr2;
  436. {
  437.   BEGIN("AddFrequency");
  438.   int i;
  439.   
  440.   for(i=0;i<256;i++)
  441.     {
  442.       *(ptr1) = *(ptr1) + *(ptr2);
  443.       ptr1++;
  444.       ptr2++;
  445.     }
  446.   *(ptr1) = MAX(*(ptr1),*(ptr2));
  447. }
  448.  
  449. /*BFUNC
  450.  
  451. InstallFrequency() is used to install a particular frequency set of
  452. arrays (denoted by the [index] scan component from the Scan
  453. parameters).
  454.  
  455. EFUNC*/
  456.  
  457. void InstallFrequency(index)
  458.      int index;
  459. {
  460.   BEGIN("InstallFrequency");
  461.   ACFrequency = CScan->ACFrequency[index];  /* Set the right pointers */
  462.   DCFrequency = CScan->DCFrequency[index];
  463.   LastDC = CScan->LastDC[index];
  464. }
  465.  
  466.  
  467. /*BFUNC
  468.  
  469. InstallPrediction() is used to install a particular DC prediction for
  470. use in frequency counting, encoding and decoding.
  471.  
  472. EFUNC*/
  473.  
  474. void InstallPrediction(index)
  475.      int index;
  476. {
  477.   BEGIN("InstallPrediction");
  478.  
  479.   LastDC = CScan->LastDC[index];   /* Set the right pointer */
  480. }
  481.  
  482. /*BFUNC
  483.  
  484. PrintACEhuff() prints out the [index] AC Huffman encoding structure in
  485. the Image structure.
  486.  
  487. EFUNC*/
  488.  
  489. void PrintACEhuff(index)
  490.      int index;
  491. {
  492.   BEGIN("PrintACEhuff");
  493.   int place;
  494.   EHUFF *eh;
  495.   int *freq;
  496.   int i,j;
  497.  
  498.   freq = CScan->ACFrequency[index];
  499.   eh = CImage->ACEhuff[index];
  500.   printf("Code:[Frequency:Size]:TotalBits\n");
  501.   for(place=0,i=0;i<8;i++)
  502.     {
  503.       for(j=0;j<8;j++)
  504.     {
  505.       printf("%2x:[%d:%d]:%d ",
  506.          place,freq[place],eh->ehufsi[place],
  507.          freq[place]*eh->ehufsi[place]);
  508.       place++;
  509.     }
  510.       printf("\n");
  511.     }
  512. }
  513.  
  514. /*BFUNC
  515.  
  516. SizeACEhuff() returns the size in bits necessary to code the
  517. particular frequency spectrum by the indexed ehuff.
  518.  
  519. EFUNC*/
  520.  
  521. int SizeACEhuff(index)
  522.      int index;
  523. {
  524.   BEGIN("SizeACEhuff");
  525.   int place,sumbits;
  526.   EHUFF *eh;
  527.   int *freq;
  528.  
  529.   freq = CScan->ACFrequency[index];
  530.   eh = CImage->ACEhuff[index];
  531.   for(sumbits=0,place=0;place<256;place++)  /* For all codes, */
  532.     {                                       /* return freq * codelength */
  533.       sumbits += freq[place]*(eh->ehufsi[place] + (place & 0x0f));
  534.     }
  535.   return(sumbits);
  536. }
  537.  
  538. /*BFUNC
  539.  
  540. PrintDCEhuff() prints out the DC encoding Huffman structure in the
  541. CImage structure according to the position specified by [index].
  542.  
  543. EFUNC*/
  544.  
  545. void PrintDCEhuff(index)
  546.      int index;
  547. {
  548.   BEGIN("PrintDCEhuff");
  549.   int place;
  550.   EHUFF *eh;
  551.   int *freq;
  552.   int i,j;
  553.  
  554.   freq = CScan->DCFrequency[index];
  555.   eh = CImage->DCEhuff[index];
  556.   printf("Code:[Frequency:Size]:TotalBits\n");
  557.   for(place=0,i=0;i<8;i++)
  558.     {
  559.       for(j=0;j<8;j++)
  560.     {
  561.       printf("%2x:[%d:%d]:%d ",
  562.          place,freq[place],eh->ehufsi[place],
  563.          freq[place]*eh->ehufsi[place]);
  564.       place++;
  565.     }
  566.       printf("\n");
  567.     }
  568. }
  569.  
  570.  
  571. /*BFUNC
  572.  
  573. SizeDCEhuff() returns the bit size of the frequency and codes held by
  574. the indexed dc codebook and frequency.
  575.  
  576. EFUNC*/
  577.  
  578. int SizeDCEhuff(index)
  579.      int index;
  580. {
  581.   BEGIN("SizeDCEhuff");
  582.   int place,sumbits;
  583.   EHUFF *eh;
  584.   int *freq;
  585.  
  586.   freq = CScan->DCFrequency[index];
  587.   eh = CImage->DCEhuff[index];
  588.   for(sumbits=0,place=0;place<256;place++) /* For all codes */
  589.     {                                      /* Return freq * codelength */
  590.       sumbits += freq[place]*(eh->ehufsi[place] + place);
  591.     }
  592.   return(sumbits);
  593. }
  594.  
  595.  
  596. /*BFUNC
  597.  
  598. LosslessFrequencyDC() is used to accumulate statistics on what DC codes occur
  599. most frequently.
  600.  
  601. EFUNC*/
  602.  
  603. void LosslessFrequencyDC(coef)
  604.      int coef;
  605. {
  606.   BEGIN("FrequencyDC");
  607.   int s,cofac;
  608.  
  609.   cofac = coef&0xffff;               /* Take modulo */
  610.   if (cofac & 0x8000)                /* if signed, then get absoulte val*/
  611.     cofac = 0x10000-cofac;
  612.  
  613.   for(s=0;cofac>=256;s+=8,cofac>>=8);               /* Find "code" */
  614.   s += csize[cofac];
  615.  
  616. #ifdef CODEC_DEBUG
  617.   printf("DC FEncoding Difference %d Size %d\n",diff,s);
  618. #endif
  619.   DCFrequency[s]++;              /* Increment frequency of such code */
  620. }
  621.  
  622. /*BFUNC
  623.  
  624. LosslessEncodeDC() encodes the input coefficient to the stream using
  625. the currently installed DC Huffman table.  The only exception is the
  626. SSSS value of 16.
  627.  
  628. EFUNC*/
  629.  
  630. void LosslessEncodeDC(coef)
  631.      int coef;
  632. {
  633.   BEGIN("EncodeDC");
  634.   int s,cofac;
  635.  
  636.   cofac = coef&0xffff;               /* Take modulo */
  637.   if (cofac & 0x8000)                /* if signed, then get absoulte val*/
  638.     cofac = 0x10000-cofac;
  639.  
  640.   for(s=0;cofac>=256;s+=8,cofac>>=8);               /* Find "code" */
  641.   s += csize[cofac];
  642.  
  643. #ifdef CODEC_DEBUG
  644.   printf("DC Encoding Difference %d Size %d\n",coeff,s);
  645. #endif
  646.   EncodeHuffman(s);              /* Encode size */
  647.   if (coef &0x8000)                  /* Encode difference */
  648.     coef--;
  649.   if (s!=16) fputv(s,coef);
  650. }
  651.  
  652. /*BFUNC
  653.  
  654. LosslessDecodeDC() is used to decode a DC value from the input stream.
  655. It returns the actual number found.
  656.  
  657. EFUNC*/
  658.  
  659. int LosslessDecodeDC()
  660. {
  661.   BEGIN("DecodeDC");
  662.   int s,coef;
  663.  
  664.   s = DecodeHuffman();
  665. #ifdef CODEC_DEBUG
  666.   printf("DC Decode sig. %d\n",s);
  667. #endif
  668.  
  669.   if (s==16)  return(32768);
  670.   else if (s)
  671.     {
  672.       coef = fgetv(s);
  673.       s--;                                /* 2's Bit Align */
  674. #ifdef CODEC_DEBUG
  675.       printf("Raw DC Decode %d\n",coef);
  676. #endif
  677.       if ((coef & bit_set_mask[s]) == 0)
  678.     {
  679.       coef |= extend_mask[s];
  680.       coef++;
  681.     }
  682.       return(coef);
  683.     }
  684.   else return(0);
  685. }
  686.  
  687. /*END*/
  688.